<!doctype html>
<meta charset="utf8">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/github.min.css">
<pre class="metadata">
title: AsyncContext
stage: 1
contributors: Chengzhong Wu, Justin Ridgewell
</pre>
<emu-biblio href="./shadowrealm-biblio.json"></emu-biblio>

<emu-clause id="sec-ecmascript-data-types-and-values">
  <h1>ECMAScript Data Types and Values</h1>

  <emu-clause id="sec-ecmascript-specification-types">
    <h1>ECMAScript Specification Types</h1>

    <ins class="block">
    <emu-clause id="sec-asynccontext-mapping-record-specification-type">
      <h1>The Async Context Mapping Record Specification Type</h1>
      <p>The <dfn variants="Async Context Mapping Records">Async Context Mapping Record</dfn> type is used to represent an AsyncContext.Variable value mapping in the surrounding Agent's [[AsyncContextMapping]].</p>
      <p>An Async Context Mapping Record's fields are defined by <emu-xref href="#table-asynccontext-mapping-record-fields"></emu-xref>.</p>

      <emu-table id="table-asynccontext-mapping-record-fields" caption="Async Context Mapping Record Fields">
        <table>
          <tr>
            <th>
              Field Name
            </th>
            <th>
              Value
            </th>
            <th>
              Meaning
            </th>
          </tr>
          <tr>
            <td>
              [[AsyncContextKey]]
            </td>
            <td>
              an AsyncContext.Variable instance
            </td>
            <td>
              The AsyncContext.Variable instance as the key in the mapping.
            </td>
          </tr>
          <tr>
            <td>
              [[AsyncContextValue]]
            </td>
            <td>
              an ECMAScript language value
            </td>
            <td>
              The value of the AsyncContext.Variable instance in the mapping.
            </td>
          </tr>
        </table>
      </emu-table>
    </emu-clause>
    </ins>
  </emu-clause>
</emu-clause>

<emu-clause id="sec-executable-code-and-execution-contexts">
  <h1>Executable Code and Execution Contexts</h1>

  <emu-clause id="sec-agents">
    <h1>Agents</h1>
    <p>This proposal adds a new field to the Agent Record as the following table:</p>
    <emu-table id="table-agent-record" caption="Agent Record Fields">
      <table>
        <tr>
          <th>Field Name</th>
          <th>Value</th>
          <th>Meaning</th>
        </tr>
        <tr>
          <td>[[LittleEndian]]</td>
          <td>a Boolean</td>
          <td>The default value computed for the <em>isLittleEndian</em> parameter when it is needed by the algorithms GetValueFromBuffer and SetValueInBuffer. The choice is implementation-defined and should be the alternative that is most efficient for the implementation. Once the value has been observed it cannot change.</td>
        </tr>
        <tr>
          <td>[[CanBlock]]</td>
          <td>a Boolean</td>
          <td>Determines whether the agent can block or not.</td>
        </tr>
        <tr>
          <td>[[Signifier]]</td>
          <td>an agent signifier</td>
          <td>Uniquely identifies the agent within its agent cluster.</td>
        </tr>
        <tr>
          <td>[[IsLockFree1]]</td>
          <td>a Boolean</td>
          <td>*true* if atomic operations on one-<emu-not-ref>byte values</emu-not-ref> are lock-free, *false* otherwise.</td>
        </tr>
        <tr>
          <td>[[IsLockFree2]]</td>
          <td>a Boolean</td>
          <td>*true* if atomic operations on two-<emu-not-ref>byte values</emu-not-ref> are lock-free, *false* otherwise.</td>
        </tr>
        <tr>
          <td>[[IsLockFree8]]</td>
          <td>a Boolean</td>
          <td>*true* if atomic operations on eight-<emu-not-ref>byte values</emu-not-ref> are lock-free, *false* otherwise.</td>
        </tr>
        <tr>
          <td>[[CandidateExecution]]</td>
          <td>a candidate execution Record</td>
          <td>See the memory model.</td>
        </tr>
        <tr>
          <td>[[KeptAlive]]</td>
          <td>a List of Objects</td>
          <td>Initially a new empty List, representing the list of objects to be kept alive until the end of the current Job</td>
        </tr>
        <tr>
          <td>
            <ins>[[AsyncContextMapping]]</ins>
          </td>
          <td>
            <ins>a List of Async Context Mapping Records</ins>
          </td>
          <td>
            <ins>A map from the AsyncContext.Variable instances to the saved ECMAScript language value. Every Record in the List contains a unique [[AsyncContextKey]]. The map is initially empty.</ins>
          </td>
        </tr>
      </table>
    </emu-table>
  </emu-clause>

  <emu-clause id="sec-weakref-processing-model">
    <h1>Processing Model of WeakRef and FinalizationRegistry Targets</h1>

    <emu-clause id="sec-weakref-host-hooks">
      <h1>Host Hooks</h1>

      <emu-clause id="sec-host-cleanup-finalization-registry" type="host-defined abstract operation">
        <h1>
          HostEnqueueFinalizationRegistryCleanupJob (
            _finalizationRegistry_: a FinalizationRegistry,
          ): ~unused~
        </h1>
        <dl class="header">
        </dl>
        <p>Let _cleanupJob_ be a new Job Abstract Closure with no parameters that captures _finalizationRegistry_ and performs the following steps when called:</p>
        <emu-alg>
          1. <ins>Let _previousContextMapping_ be AsyncContextSwap(_finalizationRegistry_.[[FinalizationRegistryAsyncContextMapping]]).</ins>
          1. Let _cleanupResult_ be Completion(CleanupFinalizationRegistry(_finalizationRegistry_)).
          1. If _cleanupResult_ is an abrupt completion, perform any host-defined steps for reporting the error.
          1. <ins>Perform AsyncContextSwap(_previousContextMapping_).</ins>
          1. Return ~unused~.
        </emu-alg>
        <p>An implementation of HostEnqueueFinalizationRegistryCleanupJob schedules _cleanupJob_ to be performed at some future time, if possible. It must also conform to the requirements in <emu-xref href="#sec-jobs"></emu-xref>.</p>
      </emu-clause>
    </emu-clause>
  </emu-clause>
</emu-clause>

<emu-clause id="sec-ordinary-and-exotic-objects-behaviours">
  <h1>Ordinary and Exotic Objects Behaviours</h1>

  <emu-clause id="sec-built-in-function-objects">
    <h1>Built-in Function Objects</h1>

    <emu-clause id="sec-createbuiltinfunction" type="abstract operation">
      <h1>
        CreateBuiltinFunction (
          _behaviour_: an Abstract Closure, a set of algorithm steps, or some other definition of a function's behaviour provided in this specification,
          optional _length_: a non-negative integer or +&infin;,
          optional _name_: a property key or a Private Name,
          optional _additionalInternalSlotsList_: a List of names of internal slots,
          optional _realm_: a Realm Record,
          optional _prototype_: an Object or *null*,
          optional _prefix_: a String,
        ): a function object
      </h1>
      <dl class="header">
        <dt>description</dt>
        <dd>_additionalInternalSlotsList_ contains the names of additional internal slots that must be defined as part of the object. This operation creates a built-in function object.</dd>
      </dl>
      <emu-alg>
        1. <ins>If _additionalInternalSlotsList_ is not present, set _additionalInternalSlotsList_ to a new empty List.</ins>
        1. If _realm_ is not present, set _realm_ to the current Realm Record.
        1. If _prototype_ is not present, set _prototype_ to _realm_.[[Intrinsics]].[[%Function.prototype%]].
        1. Let _internalSlotsList_ be a List containing the names of all the internal slots that <emu-xref href="#sec-built-in-function-objects"></emu-xref> requires for the built-in function object that is about to be created.
        1. Append to _internalSlotsList_ the elements of _additionalInternalSlotsList_.
        1. Let _func_ be a new built-in function object that, when called, performs the action described by _behaviour_ using the provided arguments as the values of the corresponding parameters specified by _behaviour_. The new function object has internal slots whose names are the elements of _internalSlotsList_, and an [[InitialName]] internal slot.
        1. Set _func_.[[Prototype]] to _prototype_.
        1. Set _func_.[[Extensible]] to *true*.
        1. Set _func_.[[Realm]] to _realm_.
        1. Set _func_.[[InitialName]] to *null*.
        1. <ins>If _length_ is present, then</ins>
          1. Perform SetFunctionLength(_func_, _length_).
        1. <ins>If _name_ is present, then</ins>
          1. If _prefix_ is not present, then
            1. Perform SetFunctionName(_func_, _name_).
          1. Else,
            1. Perform SetFunctionName(_func_, _name_, _prefix_).
        1. Return _func_.
      </emu-alg>
      <p>Each built-in function defined in this specification is created by calling the CreateBuiltinFunction abstract operation.</p>
    </emu-clause>
  </emu-clause>
  </emu-clause>
</emu-clause>

<emu-clause id="sec-ecmascript-language-functions-and-classes">
  <h1>ECMAScript Language: Functions and Classes</h1>

  <emu-clause id="sec-generator-function-definitions">
    <h1>Generator Function Definitions</h1>

    <emu-clause id="sec-generator-function-definitions-runtime-semantics-evaluation" type="sdo">
      <h1>Runtime Semantics: Evaluation</h1>
      <emu-grammar>
        GeneratorExpression : `function` `*` BindingIdentifier? `(` FormalParameters `)` `{` GeneratorBody `}`
      </emu-grammar>
      <emu-alg>
        1. Return InstantiateGeneratorFunctionExpression of |GeneratorExpression|.
      </emu-alg>
      <emu-grammar>YieldExpression : `yield`</emu-grammar>
      <emu-alg>
        1. <del>Return ? Yield(*undefined*).</del>
        1. <ins>Let _asyncContextMapping_ be AsyncContextSnapshot().</ins>
        1. <ins>Let _result_ be Completion(Yield(*undefined*)).</ins>
        1. <ins>Perform AsyncContextSwap(_asyncContextMapping_).</ins>
        1. <ins>Return ? _result_.</ins>
      </emu-alg>
      <emu-grammar>YieldExpression : `yield` AssignmentExpression</emu-grammar>
      <emu-alg>
        1. Let _exprRef_ be ? Evaluation of |AssignmentExpression|.
        1. Let _value_ be ? GetValue(_exprRef_).
        1. <del>Return ? Yield(_value_).</del>
        1. <ins>Let _asyncContextMapping_ be AsyncContextSnapshot().</ins>
        1. <ins>Let _result_ be Completion(Yield(_value_)).</ins>
        1. <ins>Perform AsyncContextSwap(_asyncContextMapping_).</ins>
        1. <ins>Return ? _result_.</ins>
      </emu-alg>
      <emu-grammar>YieldExpression : `yield` `*` AssignmentExpression</emu-grammar>
      <emu-alg>
        1. Let _generatorKind_ be GetGeneratorKind().
        1. Assert: _generatorKind_ is either ~sync~ or ~async~.
        1. Let _exprRef_ be ? Evaluation of |AssignmentExpression|.
        1. Let _value_ be ? GetValue(_exprRef_).
        1. Let _iteratorRecord_ be ? GetIterator(_value_, _generatorKind_).
        1. Let _iterator_ be _iteratorRecord_.[[Iterator]].
        1. <ins>Let _asyncContextMapping_ be AsyncContextSnapshot().</ins>
        1. Let _received_ be NormalCompletion(*undefined*).
        1. Repeat,
          1. If _received_ is a normal completion, then
            1. Let _innerResult_ be ? Call(_iteratorRecord_.[[NextMethod]], _iteratorRecord_.[[Iterator]], « _received_.[[Value]] »).
            1. If _generatorKind_ is ~async~, set _innerResult_ to ? Await(_innerResult_).
            1. If _innerResult_ is not an Object, throw a *TypeError* exception.
            1. Let _done_ be ? IteratorComplete(_innerResult_).
            1. If _done_ is *true*, then
              1. Return ? IteratorValue(_innerResult_).
            1. If _generatorKind_ is ~async~, set _received_ to Completion(AsyncGeneratorYield(? IteratorValue(_innerResult_))).
            1. Else, set _received_ to Completion(GeneratorYield(_innerResult_)).
            1. <ins>Perform AsyncContextSwap(_asyncContextMapping_).</ins>
          1. Else if _received_ is a throw completion, then
            1. Let _throw_ be ? GetMethod(_iterator_, *"throw"*).
            1. If _throw_ is not *undefined*, then
              1. Let _innerResult_ be ? Call(_throw_, _iterator_, « _received_.[[Value]] »).
              1. If _generatorKind_ is ~async~, set _innerResult_ to ? Await(_innerResult_).
              1. NOTE: Exceptions from the inner iterator `throw` method are propagated. Normal completions from an inner `throw` method are processed similarly to an inner `next`.
              1. If _innerResult_ is not an Object, throw a *TypeError* exception.
              1. Let _done_ be ? IteratorComplete(_innerResult_).
              1. If _done_ is *true*, then
                1. Return ? IteratorValue(_innerResult_).
              1. If _generatorKind_ is ~async~, set _received_ to Completion(AsyncGeneratorYield(? IteratorValue(_innerResult_))).
              1. Else, set _received_ to Completion(GeneratorYield(_innerResult_)).
              1. <ins>Perform AsyncContextSwap(_asyncContextMapping_).</ins>
            1. Else,
              1. NOTE: If _iterator_ does not have a `throw` method, this throw is going to terminate the `yield*` loop. But first we need to give _iterator_ a chance to clean up.
              1. Let _closeCompletion_ be NormalCompletion(~empty~).
              1. If _generatorKind_ is ~async~, perform ? AsyncIteratorClose(_iteratorRecord_, _closeCompletion_).
              1. Else, perform ? IteratorClose(_iteratorRecord_, _closeCompletion_).
              1. NOTE: The next step throws a *TypeError* to indicate that there was a `yield*` protocol violation: _iterator_ does not have a `throw` method.
              1. Throw a *TypeError* exception.
          1. Else,
            1. Assert: _received_ is a return completion.
            1. Let _return_ be ? GetMethod(_iterator_, *"return"*).
            1. If _return_ is *undefined*, then
              1. Set _value_ to _received_.[[Value]].
              1. If _generatorKind_ is ~async~, then
                1. Set _value_ to ? Await(_value_).
              1. Return ReturnCompletion(_value_).
            1. Let _innerReturnResult_ be ? Call(_return_, _iterator_, « _received_.[[Value]] »).
            1. If _generatorKind_ is ~async~, set _innerReturnResult_ to ? Await(_innerReturnResult_).
            1. If _innerReturnResult_ is not an Object, throw a *TypeError* exception.
            1. Let _done_ be ? IteratorComplete(_innerReturnResult_).
            1. If _done_ is *true*, then
              1. Set _value_ to ? IteratorValue(_innerReturnResult_).
              1. Return ReturnCompletion(_value_).
            1. If _generatorKind_ is ~async~, set _received_ to Completion(AsyncGeneratorYield(? IteratorValue(_innerReturnResult_))).
            1. Else, set _received_ to Completion(GeneratorYield(_innerReturnResult_)).
            1. <ins>Perform AsyncContextSwap(_asyncContextMapping_).</ins>
      </emu-alg>
    </emu-clause>
  </emu-clause>
</emu-clause>

<emu-clause id="sec-control-abstraction-objects">
  <h1>Control Abstraction Objects</h1>

  <emu-clause id="sec-promise-objects">
    <h1>Promise Objects</h1>

    <emu-clause id="sec-promise-abstract-operations">
      <h1>Promise Abstract Operations</h1>

      <emu-clause id="sec-promisereaction-records">
        <h1>PromiseReaction Records</h1>
        <p>A <dfn variants="PromiseReaction Records">PromiseReaction Record</dfn> is a Record value used to store information about how a promise should react when it becomes resolved or rejected with a given value. PromiseReaction Records are created by the PerformPromiseThen abstract operation, and are used by the Abstract Closure returned by NewPromiseReactionJob.</p>
        <p>PromiseReaction Records have the fields listed in <emu-xref href="#table-promisereaction-record-fields"></emu-xref>.</p>
        <emu-table id="table-promisereaction-record-fields" caption="PromiseReaction Record Fields" oldids="table-58">
          <table>
            <tr>
              <th>
                Field Name
              </th>
              <th>
                Value
              </th>
              <th>
                Meaning
              </th>
            </tr>
            <tr>
              <td>
                [[Capability]]
              </td>
              <td>
                a PromiseCapability Record or *undefined*
              </td>
              <td>
                The capabilities of the promise for which this record provides a reaction handler.
              </td>
            </tr>
            <tr>
              <td>
                [[Type]]
              </td>
              <td>
                ~fulfill~ or ~reject~
              </td>
              <td>
                The [[Type]] is used when [[Handler]] is ~empty~ to allow for behaviour specific to the settlement type.
              </td>
            </tr>
            <tr>
              <td>
                [[Handler]]
              </td>
              <td>
                a JobCallback Record or ~empty~
              </td>
              <td>
                The function that should be applied to the incoming value, and whose return value will govern what happens to the derived promise. If [[Handler]] is ~empty~, a function that depends on the value of [[Type]] will be used instead.
              </td>
            </tr>
            <tr>
              <td>
                <ins>[[PromiseAsyncContextMapping]]</ins>
              </td>
              <td>
                <ins>a List of Async Context Mapping Records</ins>
              </td>
              <td>
                <ins>A map from the AsyncContext.Variable instances to the saved ECMAScript language value. Every Record in the List contains a unique [[AsyncContextKey]].</ins>
              </td>
            </tr>
          </table>
        </emu-table>
      </emu-clause>

      <emu-clause id="sec-host-promise-rejection-tracker" type="host-defined abstract operation">
        <h1>
          HostPromiseRejectionTracker (
            _promise_: a Promise,
            _operation_: *"reject"* or *"handle"*,
          ): ~unused~
        </h1>
        <dl class="header">
          <dt>description</dt>
          <dd>It allows host environments to track promise rejections.</dd>
        </dl>
        <p>An implementation of HostPromiseRejectionTracker must conform to the following requirements:</p>
        <ul>
          <li>It must complete normally (i.e. not return an abrupt completion).</li>
        </ul>
        <p>The default implementation of HostPromiseRejectionTracker is to return ~unused~.</p>

        <ins class="block">
          <emu-note>
            <p>An implementation of HostPromiseRejectionTracker that delays notifying developers of unhandled rejections must conform to the following requirements</p>
            <ul>
              <li>It must perform AsyncContextSnapshot() at the call of HostPromiseRejectionTracker,</li>
              <li>It must perform AsyncContextSwap before the event notification, with the result of the AsyncContextSnapshot operation,</li>
              <li>It must perform AsyncContextSwap after the event notification, with the result of the earlier AsyncContextSwap operation.</li>
            </ul>
          </emu-note>
        </ins>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-promise-jobs">
      <h1>Promise Jobs</h1>
      <emu-clause id="sec-newpromisereactionjob" type="abstract operation" oldids="sec-promisereactionjob">
        <h1>
          NewPromiseReactionJob (
            _reaction_: a PromiseReaction Record,
            _argument_: an ECMAScript language value,
          ): a Record with fields [[Job]] (a Job Abstract Closure) and [[Realm]] (a Realm Record or *null*)
        </h1>
        <dl class="header">
          <dt>description</dt>
          <dd>It returns a new Job Abstract Closure that applies the appropriate handler to the incoming value, and uses the handler's return value to resolve or reject the derived promise associated with that handler.</dd>
        </dl>
        <emu-alg>
          1. Let _job_ be a new Job Abstract Closure with no parameters that captures _reaction_ and _argument_ and performs the following steps when called:
            1. Let _promiseCapability_ be _reaction_.[[Capability]].
            1. Let _type_ be _reaction_.[[Type]].
            1. Let _handler_ be _reaction_.[[Handler]].
            1. <ins>Let _previousContextMapping_ be AsyncContextSwap(_reaction_.[[PromiseAsyncContextMapping]]).</ins>
            1. If _handler_ is ~empty~, then
              1. If _type_ is ~fulfill~, then
                1. let _handlerResult_ be NormalCompletion(_argument_).
              1. Else,
                1. Assert: _type_ is ~reject~.
                1. Let _handlerResult_ be ThrowCompletion(_argument_).
            1. Else,
              1. let _handlerResult_ be Completion(HostCallJobCallback(_handler_, *undefined*, « _argument_ »)).
            1. If _promiseCapability_ is *undefined*, then
              1. Assert: _handlerResult_ is not an abrupt completion.
              1. <ins>Perform AsyncContextSwap(_previousContextMapping_).</ins>
              1. Return ~empty~.
            1. Assert: _promiseCapability_ is a PromiseCapability Record.
            1. If _handlerResult_ is an abrupt completion, then
              1. <del>Return ? Call(_promiseCapability_.[[Reject]], *undefined*, « _handlerResult_.[[Value]] »).</del>
              1. <ins>Let _resolvingFunctionResult_ be Completion(Call(_promiseCapability_.[[Reject]], *undefined*, « _handlerResult_.[[Value]] »)).</ins>
            1. Else,
              1. <del>Return ? Call(_promiseCapability_.[[Resolve]], *undefined*, « _handlerResult_.[[Value]] »).</del>
              1. <ins>Let _resolvingFunctionResult_ be Completion(Call(_promiseCapability_.[[Resolve]], *undefined*, « _handlerResult_.[[Value]] »)).</ins>
            1. <ins>Perform AsyncContextSwap(_previousContextMapping_).</ins>
            1. <ins>Return _resolvingFunctionResult_.</ins>
          1. Let _handlerRealm_ be *null*.
          1. If _reaction_.[[Handler]] is not ~empty~, then
            1. Let _getHandlerRealmResult_ be Completion(GetFunctionRealm(_reaction_.[[Handler]].[[Callback]])).
            1. If _getHandlerRealmResult_ is a normal completion, set _handlerRealm_ to _getHandlerRealmResult_.[[Value]].
            1. Else, set _handlerRealm_ to the current Realm Record.
            1. NOTE: _handlerRealm_ is never *null* unless the handler is *undefined*. When the handler is a revoked Proxy and no ECMAScript code runs, _handlerRealm_ is used to create error objects.
          1. Return the Record { [[Job]]: _job_, [[Realm]]: _handlerRealm_ }.
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-newpromiseresolvethenablejob" type="abstract operation" oldids="sec-promiseresolvethenablejob">
        <h1>
          NewPromiseResolveThenableJob (
            _promiseToResolve_: a Promise,
            _thenable_: an Object,
            _then_: a JobCallback Record,
          ): a Record with fields [[Job]] (a Job Abstract Closure) and [[Realm]] (a Realm Record)
        </h1>
        <dl class="header">
        </dl>
        <emu-alg>
          1. <ins>Let _mapping_ be AsyncContextSnapshot().</ins>
          1. Let _job_ be a new Job Abstract Closure with no parameters that captures _promiseToResolve_, _thenable_, _then_, <ins>and _mapping_</ins> and performs the following steps when called:
            1. Let _resolvingFunctions_ be CreateResolvingFunctions(_promiseToResolve_).
            1. <ins>Let _previousContextMapping_ be AsyncContextSwap(_mapping_).</ins>
            1. Let _thenCallResult_ be Completion(HostCallJobCallback(_then_, _thenable_, « _resolvingFunctions_.[[Resolve]], _resolvingFunctions_.[[Reject]] »)).
            1. If _thenCallResult_ is an abrupt completion, then
              1. <del>Return ? Call(_resolvingFunctions_.[[Reject]], *undefined*, « _thenCallResult_.[[Value]] »).</del>
              1. <ins>Let _rejectResult_ be Completion(Call(_resolvingFunctions_.[[Reject]], *undefined*, « _thenCallResult_.[[Value]] »)).</ins>
              1. <ins>Perform AsyncContextSwap(_previousContextMapping_).</ins>
              1. <ins>Return _rejectResult_.</ins>
            1. <ins>Perform AsyncContextSwap(_previousContextMapping_).</ins>
            1. Return ? _thenCallResult_.
          1. Let _getThenRealmResult_ be Completion(GetFunctionRealm(_then_.[[Callback]])).
          1. If _getThenRealmResult_ is a normal completion, let _thenRealm_ be _getThenRealmResult_.[[Value]].
          1. Else, let _thenRealm_ be the current Realm Record.
          1. NOTE: _thenRealm_ is never *null*. When _then_.[[Callback]] is a revoked Proxy and no code runs, _thenRealm_ is used to create error objects.
          1. Return the Record { [[Job]]: _job_, [[Realm]]: _thenRealm_ }.
        </emu-alg>
        <emu-note>
          <p>This Job uses the supplied thenable and its `then` method to resolve the given promise. This process must take place as a Job to ensure that the evaluation of the `then` method occurs after evaluation of any surrounding code has completed.</p>
        </emu-note>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-properties-of-the-promise-prototype-object">
      <h1>Properties of the Promise Prototype Object</h1>
      <p>The <dfn>Promise prototype object</dfn>:</p>
      <ul>
        <li>is <dfn>%Promise.prototype%</dfn>.</li>
        <li>has a [[Prototype]] internal slot whose value is %Object.prototype%.</li>
        <li>is an ordinary object.</li>
        <li>does not have a [[PromiseState]] internal slot or any of the other internal slots of Promise instances.</li>
      </ul>

      <emu-clause id="sec-promise.prototype.then">
        <h1>Promise.prototype.then ( _onFulfilled_, _onRejected_ )</h1>
        <p>This method performs the following steps when called:</p>
        <emu-alg>
          1. Let _promise_ be the *this* value.
          1. If IsPromise(_promise_) is *false*, throw a *TypeError* exception.
          1. Let _C_ be ? SpeciesConstructor(_promise_, %Promise%).
          1. Let _resultCapability_ be ? NewPromiseCapability(_C_).
          1. Return PerformPromiseThen(_promise_, _onFulfilled_, _onRejected_, _resultCapability_).
        </emu-alg>

        <emu-clause id="sec-performpromisethen" type="abstract operation">
          <h1>
            PerformPromiseThen (
              _promise_: a Promise,
              _onFulfilled_: an ECMAScript language value,
              _onRejected_: an ECMAScript language value,
              optional _resultCapability_: a PromiseCapability Record,
            ): an ECMAScript language value
          </h1>
          <dl class="header">
            <dt>description</dt>
            <dd>It performs the “then” operation on _promise_ using _onFulfilled_ and _onRejected_ as its settlement actions. If _resultCapability_ is passed, the result is stored by updating _resultCapability_'s promise. If it is not passed, then PerformPromiseThen is being called by a specification-internal operation where the result does not matter.</dd>
          </dl>
          <emu-alg>
            1. Assert: IsPromise(_promise_) is *true*.
            1. If _resultCapability_ is not present, then
              1. Set _resultCapability_ to *undefined*.
            1. If IsCallable(_onFulfilled_) is *false*, then
              1. Let _onFulfilledJobCallback_ be ~empty~.
            1. Else,
              1. Let _onFulfilledJobCallback_ be HostMakeJobCallback(_onFulfilled_).
            1. If IsCallable(_onRejected_) is *false*, then
              1. Let _onRejectedJobCallback_ be ~empty~.
            1. Else,
              1. Let _onRejectedJobCallback_ be HostMakeJobCallback(_onRejected_).
            1. <ins>Let _mapping_ be AsyncContextSnapshot().</ins>
            1. Let _fulfillReaction_ be the PromiseReaction Record { [[Capability]]: _resultCapability_, [[Type]]: ~fulfill~, [[Handler]]: _onFulfilledJobCallback_, <ins>[[PromiseAsyncContextMapping]]: _mapping_</ins> }.
            1. Let _rejectReaction_ be the PromiseReaction Record { [[Capability]]: _resultCapability_, [[Type]]: ~reject~, [[Handler]]: _onRejectedJobCallback_, <ins>[[PromiseAsyncContextMapping]]: _mapping_</ins>}.
            1. If _promise_.[[PromiseState]] is ~pending~, then
              1. Append _fulfillReaction_ to _promise_.[[PromiseFulfillReactions]].
              1. Append _rejectReaction_ to _promise_.[[PromiseRejectReactions]].
            1. Else if _promise_.[[PromiseState]] is ~fulfilled~, then
              1. Let _value_ be _promise_.[[PromiseResult]].
              1. Let _fulfillJob_ be NewPromiseReactionJob(_fulfillReaction_, _value_).
              1. Perform HostEnqueuePromiseJob(_fulfillJob_.[[Job]], _fulfillJob_.[[Realm]]).
            1. Else,
              1. Assert: The value of _promise_.[[PromiseState]] is ~rejected~.
              1. Let _reason_ be _promise_.[[PromiseResult]].
              1. If _promise_.[[PromiseIsHandled]] is *false*, perform HostPromiseRejectionTracker(_promise_, *"handle"*).
              1. Let _rejectJob_ be NewPromiseReactionJob(_rejectReaction_, _reason_).
              1. Perform HostEnqueuePromiseJob(_rejectJob_.[[Job]], _rejectJob_.[[Realm]]).
            1. Set _promise_.[[PromiseIsHandled]] to *true*.
            1. If _resultCapability_ is *undefined*, then
              1. Return *undefined*.
            1. Else,
              1. Return _resultCapability_.[[Promise]].
          </emu-alg>
        </emu-clause>
      </emu-clause>
    </emu-clause>
  </emu-clause>

  <emu-clause id="sec-generator-objects">
    <h1>Generator Objects</h1>

    <emu-clause id="sec-generator-abstract-operations">
      <h1>Generator Abstract Operations</h1>

      <emu-clause id="sec-generatorstart" type="abstract operation">
        <h1>
          GeneratorStart (
            _generator_: a Generator,
            _generatorBody_: a |FunctionBody| Parse Node or an Abstract Closure with no parameters,
          ): ~unused~
        </h1>
        <dl class="header">
        </dl>
        <emu-alg>
          1. Assert: The value of _generator_.[[GeneratorState]] is *undefined*.
          1. Let _genContext_ be the running execution context.
          1. Set the Generator component of _genContext_ to _generator_.
          1. <ins>Let _generatorAsyncContextMapping_ be AsyncContextSnapshot().</ins>
          1. Let _closure_ be a new Abstract Closure with no parameters that captures _generatorBody_ <ins>and _generatorAsyncContextMapping_,</ins> and performs the following steps when called:
            1. Let _acGenContext_ be the running execution context.
            1. Let _acGenerator_ be the Generator component of _acGenContext_.
            1. If _generatorBody_ is a Parse Node, then
              1. <ins>Let _callerAsyncContextMapping_ be AsyncContextSwap(_generatorAsyncContextMapping_).</ins>
              1. Let _result_ be Completion(Evaluation of _generatorBody_).
              1. <ins>Perform AsyncContextSwap(_callerAsyncContextMapping_).</ins>
            1. Else,
              1. Assert: _generatorBody_ is an Abstract Closure with no parameters.
              1. Let _result_ be _generatorBody_().
            1. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return.
            1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
            1. Set _acGenerator_.[[GeneratorState]] to ~completed~.
            1. NOTE: Once a generator enters the ~completed~ state it never leaves it and its associated execution context is never resumed. Any execution state associated with _acGenerator_ can be discarded at this point.
            1. If _result_.[[Type]] is ~normal~, then
              1. Let _resultValue_ be *undefined*.
            1. Else if _result_.[[Type]] is ~return~, then
              1. Let _resultValue_ be _result_.[[Value]].
            1. Else,
              1. Assert: _result_.[[Type]] is ~throw~.
              1. Return ? _result_.
            1. Return CreateIteratorResultObject(_resultValue_, *true*).
          1. Set the code evaluation state of _genContext_ such that when evaluation is resumed for that execution context, _closure_ will be called with no arguments.
          1. Set _generator_.[[GeneratorContext]] to _genContext_.
          1. Set _generator_.[[GeneratorState]] to ~suspended-start~.
          1. Return ~unused~.
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-generatorresume" type="abstract operation">
        <h1>
          GeneratorResume (
            _generator_: an ECMAScript language value,
            _value_: an ECMAScript language value or ~empty~,
            _generatorBrand_: a String or ~empty~,
          ): either a normal completion containing an ECMAScript language value or a throw completion
        </h1>
        <dl class="header">
        </dl>
        <emu-alg>
          1. Let _state_ be ? GeneratorValidate(_generator_, _generatorBrand_).
          1. If _state_ is ~completed~, return CreateIteratorResultObject(*undefined*, *true*).
          1. Assert: _state_ is either ~suspended-start~ or ~suspended-yield~.
          1. Let _genContext_ be _generator_.[[GeneratorContext]].
          1. Let _methodContext_ be the running execution context.
          1. Suspend _methodContext_.
          1. Set _generator_.[[GeneratorState]] to ~executing~.
          1. <ins>Let _previousContextMapping_ be AsyncContextSnapshot().</ins>
          1. Push _genContext_ onto the execution context stack; _genContext_ is now the running execution context.
          1. <emu-meta effects="user-code">Resume the suspended evaluation of _genContext_</emu-meta> using NormalCompletion(_value_) as the result of the operation that suspended it. Let _result_ be the value returned by the resumed computation.
          1. Assert: When we return here, _genContext_ has already been removed from the execution context stack and _methodContext_ is the currently running execution context.
          1. <ins>Perform AsyncContextSwap(_previousContextMapping_).</ins>
          1. Return ? _result_.
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-generatorresumeabrupt" type="abstract operation">
        <h1>
          GeneratorResumeAbrupt (
            _generator_: an ECMAScript language value,
            _abruptCompletion_: a return completion or a throw completion,
            _generatorBrand_: a String or ~empty~,
          ): either a normal completion containing an ECMAScript language value or a throw completion
        </h1>
        <dl class="header">
        </dl>
        <emu-alg>
          1. Let _state_ be ? GeneratorValidate(_generator_, _generatorBrand_).
          1. If _state_ is ~suspended-start~, then
            1. Set _generator_.[[GeneratorState]] to ~completed~.
            1. NOTE: Once a generator enters the ~completed~ state it never leaves it and its associated execution context is never resumed. Any execution state associated with _generator_ can be discarded at this point.
            1. Set _state_ to ~completed~.
          1. If _state_ is ~completed~, then
            1. If _abruptCompletion_.[[Type]] is ~return~, then
              1. Return CreateIteratorResultObject(_abruptCompletion_.[[Value]], *true*).
            1. Return ? _abruptCompletion_.
          1. Assert: _state_ is ~suspended-yield~.
          1. Let _genContext_ be _generator_.[[GeneratorContext]].
          1. Let _methodContext_ be the running execution context.
          1. Suspend _methodContext_.
          1. Set _generator_.[[GeneratorState]] to ~executing~.
          1. <ins>Let _previousContextMapping_ be AsyncContextSnapshot().</ins>
          1. Push _genContext_ onto the execution context stack; _genContext_ is now the running execution context.
          1. <emu-meta effects="user-code">Resume the suspended evaluation of _genContext_</emu-meta> using _abruptCompletion_ as the result of the operation that suspended it. Let _result_ be the Completion Record returned by the resumed computation.
          1. Assert: When we return here, _genContext_ has already been removed from the execution context stack and _methodContext_ is the currently running execution context.
          1. <ins>Perform AsyncContextSwap(_previousContextMapping_).</ins>
          1. Return ? _result_.
        </emu-alg>
      </emu-clause>
    </emu-clause>
  </emu-clause>

  <emu-clause id="sec-asyncgenerator-objects">
    <h1>AsyncGenerator Objects</h1>

    <emu-clause id="sec-asyncgenerator-abstract-operations">
      <h1>AsyncGenerator Abstract Operations</h1>

      <emu-clause id="sec-asyncgeneratorstart" type="abstract operation">
        <h1>
          AsyncGeneratorStart (
            _generator_: an AsyncGenerator,
            _generatorBody_: a |FunctionBody| Parse Node or an Abstract Closure with no parameters,
          ): ~unused~
        </h1>
        <dl class="header">
        </dl>
        <emu-alg>
          1. Assert: _generator_.[[AsyncGeneratorState]] is *undefined*.
          1. Let _genContext_ be the running execution context.
          1. Set the Generator component of _genContext_ to _generator_.
          1. <ins>Let _generatorAsyncContextMapping_ be AsyncContextSnapshot().</ins>
          1. Let _closure_ be a new Abstract Closure with no parameters that captures _generatorBody_ <ins>and _generatorAsyncContextMapping_,</ins> and performs the following steps when called:
            1. Let _acGenContext_ be the running execution context.
            1. Let _acGenerator_ be the Generator component of _acGenContext_.
            1. If _generatorBody_ is a Parse Node, then
              1. <ins>Let _callerAsyncContextMapping_ be AsyncContextSwap(_generatorAsyncContextMapping_).</ins>
              1. Let _result_ be Completion(Evaluation of _generatorBody_).
              1. <ins>Perform AsyncContextSwap(_callerAsyncContextMapping_).</ins>
            1. Else,
              1. Assert: _generatorBody_ is an Abstract Closure with no parameters.
              1. Let _result_ be Completion(_generatorBody_()).
            1. Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return.
            1. Remove _acGenContext_ from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
            1. Set _acGenerator_.[[AsyncGeneratorState]] to ~completed~.
            1. If _result_.[[Type]] is ~normal~, set _result_ to NormalCompletion(*undefined*).
            1. If _result_.[[Type]] is ~return~, set _result_ to NormalCompletion(_result_.[[Value]]).
            1. Perform AsyncGeneratorCompleteStep(_acGenerator_, _result_, *true*).
            1. Perform AsyncGeneratorDrainQueue(_acGenerator_).
            1. Return *undefined*.
          1. Set the code evaluation state of _genContext_ such that when evaluation is resumed for that execution context, _closure_ will be called with no arguments.
          1. Set _generator_.[[AsyncGeneratorContext]] to _genContext_.
          1. Set _generator_.[[AsyncGeneratorState]] to ~suspended-start~.
          1. Set _generator_.[[AsyncGeneratorQueue]] to a new empty List.
          1. Return ~unused~.
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-asyncgeneratorresume" type="abstract operation">
        <h1>
          AsyncGeneratorResume (
            _generator_: an AsyncGenerator,
            _completion_: a Completion Record,
          ): ~unused~
        </h1>
        <dl class="header">
        </dl>
        <emu-alg>
          1. Assert: _generator_.[[AsyncGeneratorState]] is either ~suspended-start~ or ~suspended-yield~.
          1. Let _genContext_ be _generator_.[[AsyncGeneratorContext]].
          1. Let _callerContext_ be the running execution context.
          1. Suspend _callerContext_.
          1. Set _generator_.[[AsyncGeneratorState]] to ~executing~.
          1. <ins>Let _previousContextMapping_ be AsyncContextSwap(_generator_.[[AsyncGeneratorAsyncContextMapping]]).</ins>
          1. Push _genContext_ onto the execution context stack; _genContext_ is now the running execution context.
          1. <emu-meta effects="user-code">Resume the suspended evaluation of _genContext_</emu-meta> using _completion_ as the result of the operation that suspended it. Let _result_ be the Completion Record returned by the resumed computation.
          1. Assert: _result_ is never an abrupt completion.
          1. Assert: When we return here, _genContext_ has already been removed from the execution context stack and _callerContext_ is the currently running execution context.
          1. <ins>Perform AsyncContextSwap(_previousContextMapping_).</ins>
          1. Return ~unused~.
        </emu-alg>
      </emu-clause>
    </emu-clause>
  </emu-clause>

  <ins class="block">
  <emu-clause id="sec-asynccontext-object">
    <h1>The AsyncContext Object</h1>
    <p>The AsyncContext object:</p>
    <ul>
      <li>is the intrinsic object <dfn>%AsyncContext%</dfn>.</li>
      <li>is the initial value of the *"AsyncContext"* property of the global object.</li>
      <li>is an ordinary object.</li>
      <li>has a [[Prototype]] internal slot whose value is %Object.prototype%.</li>
      <li>is not a function object.</li>
      <li>does not have a [[Construct]] internal method; it cannot be used as a constructor with the `new` operator.</li>
      <li>does not have a [[Call]] internal method; it cannot be invoked as a function.</li>
    </ul>

    <emu-clause id="sec-asynccontext-abstract-operations">
      <h1>AsyncContext Abstract Operations</h1>
      <emu-clause id="sec-asynccontextsnapshot" type="abstract operation">
        <h1>
          AsyncContextSnapshot (
          ): a List of Async Context Mapping Records
        </h1>
        <dl class="header">
          <dt>description</dt>
          <dd>It is used to snapshot the surrounding agent's Agent Record's [[AsyncContextMapping]].</dd>
        </dl>
        <emu-alg>
          1. Let _agentRecord_ be the surrounding agent's Agent Record.
          1. Return _agentRecord_.[[AsyncContextMapping]].
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-asynccontextswap" type="abstract operation">
        <h1>
          AsyncContextSwap (
            _snapshotMapping_: a List of Async Context Mapping Records
          ): a List of Async Context Mapping Records
        </h1>
        <dl class="header">
          <dt>description</dt>
          <dd>It is used to swap the surrounding agent's Agent Record's [[AsyncContextMapping]] with the _snapshotMapping_.</dd>
        </dl>
        <emu-alg>
          1. Let _agentRecord_ be the surrounding agent's Agent Record.
          1. Let _asyncContextMapping_ be _agentRecord_.[[AsyncContextMapping]].
          1. Set _agentRecord_.[[AsyncContextMapping]] to _snapshotMapping_.
          1. Return _asyncContextMapping_.
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-createasynccontextsnapshot" type="abstract operation">
        <h1>
          CreateAsyncContextSnapshot (
            _snapshotMapping_: a List of Async Context Mapping Records
          ): either a normal completion containing an AsyncContext.Snapshot object or a throw completion
        </h1>
        <dl class="header">
          <dt>description</dt>
          <dd>It is used to obtain an AsyncContext.Snapshot object representing the given List of Async Context Mapping Records.</dd>
        </dl>
        <emu-alg>
          1. Let _asyncSnapshot_ be ? OrdinaryCreateFromConstructor(%AsyncContext.Snapshot%, *"%AsyncContext.Snapshot.prototype%"*, « [[AsyncSnapshotMapping]] »).
          1. Set _asyncSnapshot_.[[AsyncSnapshotMapping]] to _snapshotMapping_.
          1. Return _asyncSnapshot_.
        </emu-alg>
        <emu-note>
          <p>This abstract operation is meant for hosts to use, and it is not used in this specification.</p>
        </emu-note>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-constructor-properties-of-the-asynccontext-object">
      <h1>Constructor Properties of the AsyncContext Object</h1>

      <emu-clause id="sec-asynccontext.snapshot">
        <h1>AsyncContext.Snapshot ( . . . )</h1>
        <p>See <emu-xref href="#sec-asynccontext-snapshot-objects"></emu-xref>.</p>
      </emu-clause>

      <emu-clause id="sec-asynccontext.variable">
        <h1>AsyncContext.Variable ( . . . )</h1>
        <p>See <emu-xref href="#sec-asynccontext-variable-objects"></emu-xref>.</p>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-value-properties-of-the-asynccontext-object">
      <h1>Value Properties of the AsyncContext Object</h1>

      <emu-clause id="sec-asynccontext-@@tostringtag">
        <h1>AsyncContext [ @@toStringTag ]</h1>
        <p>The initial value of the @@toStringTag property is the String value *"AsyncContext"*.</p>
        <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>
      </emu-clause>
    </emu-clause>
  </emu-clause>

  <emu-clause id="sec-asynccontext-snapshot-objects">
    <h1>AsyncContext.Snapshot Objects</h1>

    <emu-clause id="sec-asynccontext-snapshot-constructor">
      <h1>The AsyncContext.Snapshot Constructor</h1>
      <p>The AsyncContext.Snapshot constructor:</p>
      <ul>
        <li>is <dfn>%AsyncContext.Snapshot%</dfn>.</li>
        <li>is the initial value of the *"Snapshot"* property of the %AsyncContext% object.</li>
        <li>creates and initializes a new AsyncContext.Snapshot when called as a constructor.</li>
        <li>is not intended to be called as a function and will throw an exception when called in that manner.</li>
        <li>may be used as the value in an `extends` clause of a class definition. Subclass constructors that intend to inherit the specified AsyncContext.Snapshot behaviour must include a `super` call to the AsyncContext.Snapshot constructor to create and initialize the subclass instance with the internal state necessary to support the `AsyncContext.Snapshot` and `AsyncContext.Snapshot.prototype` built-in methods.</li>
      </ul>

      <emu-clause id="sec-asynccontext-snapshot">
        <h1>AsyncContext.Snapshot ( )</h1>
        <p>This function performs the following steps when called:</p>

        <emu-alg>
          1. If NewTarget is *undefined*, throw a *TypeError* exception.
          1. Let _snapshotMapping_ be AsyncContextSnapshot().
          1. Let _asyncSnapshot_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%AsyncContext.Snapshot.prototype%"*, « [[AsyncSnapshotMapping]] »).
          1. Set _asyncSnapshot_.[[AsyncSnapshotMapping]] to _snapshotMapping_.
          1. Return _asyncSnapshot_.
        </emu-alg>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-properties-of-the-asynccontext-snapshot-constructor">
      <h1>Properties of the AsyncContext.Snapshot Constructor</h1>
      <p>The AsyncContext.Snapshot constructor:</p>
      <ul>
        <li>has a [[Prototype]] internal slot whose value is %Function.prototype%.</li>
        <li>has the following properties:</li>
      </ul>

      <emu-clause id="sec-asynccontext-snapshot.prototype">
        <h1>AsyncContext.Snapshot.prototype</h1>
        <p>The initial value of `AsyncContext.Snapshot.prototype` is the AsyncContext.Snapshot prototype object.</p>
        <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>
      </emu-clause>

      <emu-clause id="sec-asynccontext-snapshot.wrap">
        <h1>AsyncContext.Snapshot.wrap ( _fn_ )</h1>
        <p>This function returns a new function which restores the current value of all AsyncContext.Variable values when being invoked.</p>

        <emu-alg>
          1. If IsCallable(_fn_) is *false*, throw a *TypeError* exception.
          1. Let _mapping_ be AsyncContextSnapshot().
          1. Let _closure_ be a new Abstract Closure with parameters (..._args_) that captures _fn_ and _mapping_ and performs the following steps when called:
            1. Let _thisArgument_ be the *this* value.
            1. Let _previousContextMapping_ be AsyncContextSwap(_mapping_).
            1. Let _result_ be Completion(Call(_fn_, _thisArgument_, _args_)).
            1. AsyncContextSwap(_previousContextMapping_).
            1. Return _result_.
          1. Let _wrapped_ be CreateBuiltinFunction(_closure_).
          1. Perform ? CopyNameAndLength(_wrapped_, _fn_, *"wrapped"*).
          1. Return _wrapped_.
        </emu-alg>

        <emu-note type="editor">
          This algorithm uses the CopyNameAndLength AO defined in the ShadowRealm proposal. Since that AO does not depend on the rest of the ShadowRealm proposal, its definition (along with the changes to Function.prototype.bind) could be moved to this proposal if it were to advance stages beyond ShadowRealm.
        </emu-note>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-properties-of-the-asynccontext-snapshot-prototype-object">
      <h1>Properties of the AsyncContext.Snapshot Prototype Object</h1>
      <p>The <dfn>AsyncContext.Snapshot prototype object</dfn>:</p>
      <ul>
        <li>is <dfn>%AsyncContext.Snapshot.prototype%</dfn>.</li>
        <li>has a [[Prototype]] internal slot whose value is %Object.prototype%.</li>
        <li>is an ordinary object.</li>
        <li>does not have any of the other internal slots of AsyncContext.Snapshot instances.</li>
      </ul>

      <emu-clause id="sec-asynccontext-snapshot.prototype.constructor">
        <h1>AsyncContext.Snapshot.prototype.constructor</h1>
        <p>The initial value of `AsyncContext.Snapshot.prototype.constructor` is %AsyncContext.Snapshot%.</p>
      </emu-clause>

      <emu-clause id="sec-asynccontext-snapshot.prototype.run">
        <h1>AsyncContext.Snapshot.prototype.run ( _func_, ..._args_ )</h1>
        <p>This method performs the following steps when called:</p>
        <emu-alg>
          1. Let _asyncSnapshot_ be the *this* value.
          1. Perform ? RequireInternalSlot(_asyncSnapshot_, [[AsyncSnapshotMapping]]).
          1. Let _previousContextMapping_ be AsyncContextSwap(_asyncSnapshot_.[[AsyncSnapshotMapping]]).
          1. Let _result_ be Completion(Call(_func_, *undefined*, _args_)).
          1. AsyncContextSwap(_previousContextMapping_).
          1. Return _result_.
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-asynccontext-snapshot.prototype-@@tostringtag">
        <h1>AsyncContext.Snapshot.prototype [ @@toStringTag ]</h1>
        <p>The initial value of the @@toStringTag property is the String value *"AsyncContext.Snapshot"*.</p>
        <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-properties-of-asynccontext-snapshot-instances">
      <h1>Properties of AsyncContext.Snapshot Instances</h1>
      <p>AsyncContext.Snapshot instances are ordinary objects that inherit properties from the AsyncContext.Snapshot prototype object (the intrinsic, %AsyncContext.Snapshot.prototype%). AsyncContext.Snapshot instances are initially created with the internal slots described in <emu-xref href="#table-internal-slots-of-asynccontext-snapshot-instances"></emu-xref>.</p>

      <emu-table id="table-internal-slots-of-asynccontext-snapshot-instances" caption="Internal Slots of AsyncContext-Snapshot Instances">
        <table>
          <tr>
            <th>
              Internal Slot
            </th>
            <th>
              Type
            </th>
            <th>
              Description
            </th>
          </tr>
          <tr>
            <td>
              [[AsyncSnapshotMapping]]
            </td>
            <td>
              a List of Async Context Mapping Records
            </td>
            <td>
              Represents the snapshotted surrounding agent's Agent Record's [[AsyncContextMapping]] of the AsyncContext.Snapshot instance.
            </td>
          </tr>
        </table>
      </emu-table>
    </emu-clause>
  </emu-clause>

  <emu-clause id="sec-asynccontext-variable-objects">
    <h1>AsyncContext.Variable Objects</h1>

    <emu-clause id="sec-asynccontext-variable-constructor">
      <h1>The AsyncContext.Variable Constructor</h1>
      <p>The AsyncContext.Variable constructor:</p>
      <ul>
        <li>is <dfn>%AsyncContext.Variable%</dfn>.</li>
        <li>is the initial value of the *"Variable"* property of the %AsyncContext% object.</li>
        <li>creates and initializes a new AsyncContext.Variable when called as a constructor.</li>
        <li>is not intended to be called as a function and will throw an exception when called in that manner.</li>
        <li>may be used as the value in an `extends` clause of a class definition. Subclass constructors that intend to inherit the specified AsyncContext.Variable behaviour must include a `super` call to the AsyncContext.Variable constructor to create and initialize the subclass instance with the internal state necessary to support the `AsyncContext.Variable.prototype` built-in methods.</li>
      </ul>

      <emu-clause id="sec-asynccontext-variable">
        <h1>AsyncContext.Variable ( _options_ )</h1>
        <p>This function performs the following steps when called:</p>

        <emu-alg>
          1. If NewTarget is *undefined*, throw a *TypeError* exception.
          1. Let _nameStr_ be the empty String.
          1. Let _defaultValue_ be *undefined*.
          1. If _options_ is an Object, then
            1. Let _namePresent_ be ? HasProperty(_options_, *"name"*).
            1. If _namePresent_ is *true*, then
              1. Let _name_ be ? Get(_options_, *"name"*).
              1. Set _nameStr_ to ? ToString(_name_).
            1. Set _defaultValue_ to ? Get(_options_, *"defaultValue"*).
          1. Let _asyncVariable_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%AsyncContext.Variable.prototype%"*, « [[AsyncVariableName]], [[AsyncVariableDefaultValue]] »).
          1. Set _asyncVariable_.[[AsyncVariableName]] to _nameStr_.
          1. Set _asyncVariable_.[[AsyncVariableDefaultValue]] to _defaultValue_.
          1. Return _asyncVariable_.
        </emu-alg>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-properties-of-the-asynccontext-variable-constructor">
      <h1>Properties of the AsyncContext.Variable Constructor</h1>
      <p>The AsyncContext.Variable constructor:</p>
      <ul>
        <li>has a [[Prototype]] internal slot whose value is %Function.prototype%.</li>
        <li>has the following properties:</li>
      </ul>

      <emu-clause id="sec-asynccontext-variable.prototype">
        <h1>AsyncContext.Variable.prototype</h1>
        <p>The initial value of `AsyncContext.Variable.prototype` is the AsyncContext.Variable prototype object.</p>
        <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-properties-of-the-asynccontext-variable-prototype-object">
      <h1>Properties of the AsyncContext.Variable Prototype Object</h1>
      <p>The <dfn>AsyncContext.Variable prototype object</dfn>:</p>
      <ul>
        <li>is <dfn>%AsyncContext.Variable.prototype%</dfn>.</li>
        <li>has a [[Prototype]] internal slot whose value is %Object.prototype%.</li>
        <li>is an ordinary object.</li>
        <li>does not have any of the other internal slots of AsyncContext.Variable instances.</li>
      </ul>

      <emu-clause id="sec-asynccontext-variable.prototype.constructor">
        <h1>AsyncContext.Variable.prototype.constructor</h1>
        <p>The initial value of `AsyncContext.Variable.prototype.constructor` is %AsyncContext.Variable%.</p>
      </emu-clause>

      <emu-clause id="sec-asynccontext-variable.prototype.run">
        <h1>AsyncContext.Variable.prototype.run ( _value_, _func_, ..._args_ )</h1>
        <p>This method performs the following steps when called:</p>
        <emu-alg>
          1. Let _asyncVariable_ be the *this* value.
          1. Perform ? RequireInternalSlot(_asyncVariable_, [[AsyncVariableName]]).
          1. Let _previousContextMapping_ be AsyncContextSnapshot().
          1. Let _asyncContextMapping_ be a new empty List.
          1. For each Async Context Mapping Record _p_ of _previousContextMapping_, do
            1. If SameValueZero(_p_.[[AsyncContextKey]], _asyncVariable_) is *false*, then
              1. Let _q_ be the Async Context Mapping Record { [[AsyncContextKey]]: _p_.[[AsyncContextKey]], [[AsyncContextValue]]: _p_.[[AsyncContextValue]] }.
              1. Append _q_ to _asyncContextMapping_.
          1. Assert: _asyncContextMapping_ does not contain an Async Context Mapping Record whose [[AsyncContextKey]] is _asyncVariable_.
          1. Let _p_ be the Async Context Mapping Record { [[AsyncContextKey]]: _asyncVariable_, [[AsyncContextValue]]: _value_ }.
          1. Append _p_ to _asyncContextMapping_.
          1. AsyncContextSwap(_asyncContextMapping_).
          1. Let _result_ be Completion(Call(_func_, *undefined*, _args_)).
          1. AsyncContextSwap(_previousContextMapping_).
          1. Return _result_.
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-asynccontext-variable.prototype.name">
        <h1>get AsyncContext.Variable.prototype.name</h1>
        <p>`AsyncContext.Variable.prototype.name` is an accessor property whose set accessor function is *undefined*. Its get accessor function performs the following steps when called:</p>
        <emu-alg>
          1. Let _asyncVariable_ be the *this* value.
          1. Perform ? RequireInternalSlot(_asyncVariable_, [[AsyncVariableName]]).
          1. Return _asyncVariable_.[[AsyncVariableName]].
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-asynccontext-variable.prototype.get">
        <h1>AsyncContext.Variable.prototype.get ( )</h1>
        <p>This method performs the following steps when called:</p>
        <emu-alg>
          1. Let _asyncVariable_ be the *this* value.
          1. Perform ? RequireInternalSlot(_asyncVariable_, [[AsyncVariableDefaultValue]]).
          1. Let _agentRecord_ be the surrounding agent's Agent Record.
          1. Let _asyncContextMapping_ be _agentRecord_.[[AsyncContextMapping]].
          1. For each Async Context Mapping Record _p_ of _asyncContextMapping_, do
            1. If SameValueZero(_p_.[[AsyncContextKey]], _asyncVariable_) is *true*, return _p_.[[AsyncContextValue]].
          1. Return _asyncVariable_.[[AsyncVariableDefaultValue]].
        </emu-alg>
      </emu-clause>

      <emu-clause id="sec-asynccontext-variable.prototype-@@tostringtag">
        <h1>AsyncContext.Variable.prototype [ @@toStringTag ]</h1>
        <p>The initial value of the @@toStringTag property is the String value *"AsyncContext.Variable"*.</p>
        <p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>
      </emu-clause>
    </emu-clause>

    <emu-clause id="sec-properties-of-asynccontext-variable-instances">
      <h1>Properties of AsyncContext.Variable Instances</h1>
      <p>AsyncContext.Variable instances are ordinary objects that inherit properties from the AsyncContext.Variable prototype object (the intrinsic, %AsyncContext.Variable.prototype%). AsyncContext.Variable instances are initially created with the internal slots described in <emu-xref href="#table-internal-slots-of-asynccontext-variable-instances"></emu-xref>.</p>

      <emu-table id="table-internal-slots-of-asynccontext-variable-instances" caption="Internal Slots of AsyncContext.Variable Instances">
        <table>
          <tr>
            <th>
              Internal Slot
            </th>
            <th>
              Type
            </th>
            <th>
              Description
            </th>
          </tr>
          <tr>
            <td>
              [[AsyncVariableName]]
            </td>
            <td>
              a String
            </td>
            <td>
              The name of the AsyncContext.Variable instance.
            </td>
          </tr>
          <tr>
            <td>
              [[AsyncVariableDefaultValue]]
            </td>
            <td>
              an ECMAScript language value
            </td>
            <td>
              The default value of the AsyncContext.Variable instance when no entry is found in the mapping.
            </td>
          </tr>
        </table>
      </emu-table>
    </emu-clause>
  </emu-clause>
  </ins>
</emu-clause>

<emu-clause id="sec-managing-memory">
  <h1>Managing Memory</h1>

  <emu-clause id="sec-finalization-registry-objects">
    <h1>FinalizationRegistry Objects</h1>
    <p>A FinalizationRegistry is an object that manages registration and unregistration of cleanup operations that are performed when target objects and symbols are garbage collected.</p>

    <emu-clause id="sec-finalization-registry-constructor">
      <h1>The FinalizationRegistry Constructor</h1>
      <p>The <dfn variants="FinalizationRegistrys">FinalizationRegistry</dfn> constructor:</p>
      <ul>
        <li>is <dfn>%FinalizationRegistry%</dfn>.</li>
        <li>
          is the initial value of the *"FinalizationRegistry"* property of the global object.
        </li>
        <li>
          creates and initializes a new FinalizationRegistry when called as a constructor.
        </li>
        <li>
          is not intended to be called as a function and will throw an exception when called in that manner.
        </li>
        <li>
          may be used as the value in an `extends` clause of a class definition. Subclass constructors that intend to inherit the specified `FinalizationRegistry` behaviour must include a `super` call to the `FinalizationRegistry` constructor to create and initialize the subclass instance with the internal state necessary to support the `FinalizationRegistry.prototype` built-in methods.
        </li>
      </ul>

      <emu-clause id="sec-finalization-registry-cleanup-callback">
        <h1>FinalizationRegistry ( _cleanupCallback_ )</h1>
        <p>This function performs the following steps when called:</p>
        <emu-alg>
          1. If NewTarget is *undefined*, throw a *TypeError* exception.
          1. If IsCallable(_cleanupCallback_) is *false*, throw a *TypeError* exception.
          1. Let _finalizationRegistry_ be ? OrdinaryCreateFromConstructor(NewTarget, *"%FinalizationRegistry.prototype%"*, « [[Realm]], [[CleanupCallback]], [[Cells]], [[FinalizationRegistryAsyncContextMapping]] »).
          1. Let _fn_ be the active function object.
          1. Set _finalizationRegistry_.[[Realm]] to _fn_.[[Realm]].
          1. Set _finalizationRegistry_.[[CleanupCallback]] to HostMakeJobCallback(_cleanupCallback_).
          1. Set _finalizationRegistry_.[[Cells]] to a new empty List.
          1. <ins>Set _finalizationRegistry_.[[FinalizationRegistryAsyncContextMapping]] to AsyncContextSnapshot().</ins>
          1. Return _finalizationRegistry_.
        </emu-alg>
      </emu-clause>
    </emu-clause>
  </emu-clause>
</emu-clause>
